﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq.Expressions;

namespace Atha.Clients.ViewModels
{
	public abstract class ViewModelBase : INotifyPropertyChanging, INotifyPropertyChanged, IDisposable
	{
		public ViewModelBase()
		{
			this.Disposables = new List<IDisposable>();
		}

		protected List<IDisposable> Disposables { get; private set; }

		public event PropertyChangedEventHandler PropertyChanged;

		public event PropertyChangingEventHandler PropertyChanging;

		protected void OnPropertyChanged<T>(Expression<Func<T>> propertyExpression)
		{
			if (this.PropertyChanged != null)
			{
				this.PropertyChanged(this, new PropertyChangedEventArgs(GetPropertyName(propertyExpression)));
			}
		}

		protected void OnPropertyChanging<T>(Expression<Func<T>> propertyExpression)
		{
			if (this.PropertyChanging != null)
			{
				this.PropertyChanging(this, new PropertyChangingEventArgs(GetPropertyName(propertyExpression)));
			}
		}

		protected static string GetPropertyName<T>(Expression<Func<T>> propertyExpression)
		{
			var memberExpression = propertyExpression.Body as MemberExpression;
			var propertyName = memberExpression.Member.Name;

			return propertyName;
		}

		public void Dispose()
		{
			this.Dispose(true);
			GC.SuppressFinalize(this);
		}

		private void Dispose(bool disposing)
		{
			if (disposing)
			{
				if (this.Disposables != null)
				{
					foreach (var disposable in this.Disposables)
					{
						if (disposable != null) disposable.Dispose();
					}
				}
			}
		}

		~ViewModelBase()
		{
			this.Dispose(false);
		}
	}
}